/**
 *  Version:     @(#)aio_util.h    1.2.14 18/07/2007
 *
 *  Authors:     Hailong Xia <hlxxxx@gmail.com> 
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty 
 *  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See 
 *  the GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General
 *  Public License along with this library; if not, write to the 
 *  Free Software Foundation, Inc., 59 Temple Place, Suite 330, 
 *  Boston, MA 02111-1307  USA
 */

#ifndef __AIO_UTIL_H
#define __AIO_UTIL_H

#ifdef __cplusplus
extern "C" {
#endif

#ifndef timercmp
#define timercmp(tvp, uvp, cmp)                                 \
        (((tvp)->tv_sec == (uvp)->tv_sec) ?                     \
        ((tvp)->tv_usec cmp (uvp)->tv_usec) :                   \
        ((tvp)->tv_sec cmp (uvp)->tv_sec))
#endif

#ifndef timeradd
#define timeradd(tvp, uvp, vvp)                                 \
do {                                                            \
        (vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec;          \
        (vvp)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec;       \
        if ((vvp)->tv_usec >= 1000000) {                        \
                (vvp)->tv_sec++;                                \
                (vvp)->tv_usec -= 1000000;                      \
        }                                                       \
} while (0)
#endif

#ifndef timersub
#define timersub(tvp, uvp, vvp)                                 \
do {                                                            \
        (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec;          \
        (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec;       \
        if ((vvp)->tv_usec < 0) {                               \
                (vvp)->tv_sec--;                                \
                (vvp)->tv_usec += 1000000;                      \
        }                                                       \
} while (0)
#endif

#define FREELIST_HEAD(name, size)                               \
struct name {                                                   \
        unsigned fl_size;                                       \
        unsigned fl_count;                                      \
        void*    fl_nodes[size];                                \
}

#define FREELIST_INIT(head, size)                               \
do {                                                            \
        (head)->fl_size = size; (head)->fl_count = 0;           \
} while (0)
        
#define FREELIST_PUSH(head, node)                               \
        ((head)->fl_count == (head)->fl_size ? 0 :              \
        ((head)->fl_nodes[(head)->fl_count++] = node))

#define FREELIST_POP(head)                                      \
        ((head)->fl_count == 0 ? NULL :                         \
        (head)->fl_nodes[--(head)->fl_count])

#define FREELIST_EMPTY(head) ((head)->fl_count == 0)


#ifdef _WIN32
int gettimeofday(struct timeval *tv, struct timezone *tz);
#endif

#ifdef _AIO_DEBUG
void view_buffer(const char *buf, int size);
#endif

#ifdef __cplusplus
}
#endif


#endif /* __AIO_UTIL_H */
